package org.datascooter.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;

import org.datascooter.utils.TypeUtils;
import org.datascooter.utils.ValueHook;
import org.datascooter.utils.policy.Constraint;

/**
 * Holds value of some attribute and constraint
 * 
 * @author nemo
 * 
 */
public class LogicValue extends Data {

	private static final long serialVersionUID = 2823635037183311715L;
	Object value;
	Constraint constraint;
	public String attribute;
	String conditionId;
	String valueClass;
	String valueString;
	public transient ValueHook hook;
	private int hashCode;

	public LogicValue() {
	}

	public LogicValue(String attribute, String constraint, Object value) {
		this(attribute, Constraint.valueOf(constraint), value);
	}

	public LogicValue(String attribute, Constraint constraint, Object value) {
		this.attribute = attribute;
		this.constraint = constraint;
		this.setValue(value);
		hashCode = buildHash();
	}

	@Override
	public int hashCode() {
		return hashCode;
	}

	public int buildHash() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((constraint == null) ? 0 : constraint.hashCode());
		result = prime * result + ((attribute == null) ? 0 : attribute.hashCode());
		// result = prime * result + ((value == null) ? 0 : value.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		LogicValue other = (LogicValue) obj;
		if (hashCode != other.hashCode)
			return false;
		return true;
	}

	public Object getValue() {
		if ((value == null) && (valueString != null)) {
			if (valueClass.equalsIgnoreCase(String.class.getName())) {
				value = valueString;
			} else if (valueClass.equalsIgnoreCase(Integer.class.getName())) {
				value = new Integer(valueString);
			} else if (valueClass.equalsIgnoreCase(Long.class.getName())) {
				value = new Long(valueString);
			} else if (valueClass.equalsIgnoreCase(Boolean.class.getName())) {
				value = Boolean.valueOf(valueString);
			} else if (valueClass.equalsIgnoreCase(Date.class.getName())) {
				try {
					value = TypeUtils.parseDate(valueString);
				} catch (ParseException e) {
					e.printStackTrace();
				}
			} else if (valueClass.equalsIgnoreCase(BigDecimal.class.getName())) {
				value = new BigDecimal(valueString);
			} else if (valueClass.equalsIgnoreCase(Float.class.getName())) {
				value = new Float(valueString);
			} else if (valueClass.equalsIgnoreCase(Double.class.getName())) {
				value = new Double(valueString);
			} else {
				value = valueString;
			}
		}
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
		if (this.value != null) {
			this.valueClass = this.value.getClass().getName();
			if (value instanceof Date) {
				this.valueString = TypeUtils.formatDate((Date) value);
			} else {
				this.valueString = this.value + "";
			}
		}
	}

	public void setHook(String entity, String attribute, String order) {
		this.hook = new ValueHook(entity, attribute, order);
	}

	@Override
	public String toString() {
		return attribute + " " + Constraint.toString(constraint) + " " + value;
	}
}
